
goog.provide('esn.BaseSurvey');

goog.require('esn.constants');
goog.require('goog.ui.Component');
goog.require('goog.dom.classes');


/**
 * @constructor
 */
esn.BaseSurvey = function(appContext, sectionId, opt_domHelper) {
  goog.base(this, opt_domHelper);

  this.sectionId_ = sectionId;

  this.appContext_ = appContext;
};
goog.inherits(esn.BaseSurvey, goog.ui.Component);

esn.BaseSurvey.EventType = {
  CHANGE: goog.events.getUniqueId('change')
};

esn.BaseSurvey.prototype.enterDocument = function() {
  goog.base(this, 'enterDocument');

  this.getHandler().listen(
      this,
      esn.Question.EventType.CHANGE,
      this.handleQuestionChange);
};

esn.BaseSurvey.prototype.getSectionId = function() {
  return this.sectionId_;
};

esn.BaseSurvey.prototype.getQuestions = function() {
  goog.abstractMethod();
};

/**
 * @protected
 */
esn.BaseSurvey.prototype.getAnsweredCount = function() {
  var answeredQuestions = goog.array.filter(this.getQuestions(),
      function(question) {
    return question.isAnswered();
  });
  return answeredQuestions.length;
};

/**
 * @protected
 */
esn.BaseSurvey.prototype.createSectionQuestions = function(sectionEl,
    questionsJson, answerMap) {
  var questions = [];
  var questionEls = this.getDomHelper().getElementsByClass('questionSection',
      sectionEl);
  goog.array.forEach(questionEls, function(questionEl, index) {
    var questionModel = new esn.model.QuestionModel(questionsJson[index],
        this.sectionId_);
    var answerModel = goog.object.get(answerMap, questionModel.getId());
    var question = new esn.Question(this.appContext_, questionModel, index,
        answerModel);
    this.addChild(question);
    question.decorate(questionEl);
    questions.push(question);
  }, this);
  return questions;
};

/**
 * @protected
 */
esn.BaseSurvey.prototype.createAnswerMap = function(response) {
  if (response.hasError()) {
    return {};
  }

  var answerMap = {};
  goog.array.forEach(response.getData(), function(answer) {
    answerMap[answer.getQuestionId()] = answer;
  });
  return answerMap;
};

/**
 * @protected
 */
esn.BaseSurvey.prototype.handleQuestionChange = function() {
  this.dispatchEvent(new esn.BaseSurvey.ChangeEvent(
      this.sectionId_,
      this.getQuestions().length,
      this.getAnsweredCount()));
};

/**
 * @protected
 */
esn.BaseSurvey.prototype.validateQuestions = function() {
  var isValid = true;
  var questions = this.getQuestions();
  goog.array.forEach(questions, function(question, index) {
    if (!question.isAnswered()) {
      question.highlightAsUnanswered();

      // If this is the first occurence scroll to this section of the page.
      if (isValid) {
        if (index == 0) {
          // Top question is missing so scroll to top of page.
          goog.dom.getElement('applicationContainer').scrollIntoView(true);
        } else {
          // Scroll to the previous question so that our question is visible.
          questions[index - 1].getElement().scrollIntoView(true);
        }
      }
      isValid = false;
    }
  });
  return isValid;
};


/**
 * @constructor
 */
esn.BaseSurvey.ChangeEvent = function(sectionId, numQuestions, numAnswered) {
  goog.base(this, esn.BaseSurvey.EventType.CHANGE);
  this.sectionId_ = sectionId;
  this.numQuestions_ = numQuestions;
  this.numAnswered_ = numAnswered;
};
goog.inherits(esn.BaseSurvey.ChangeEvent, goog.events.Event);

esn.BaseSurvey.ChangeEvent.prototype.getSectionId = function() {
  return this.sectionId_;
};

esn.BaseSurvey.ChangeEvent.prototype.getPercentCompleted = function() {
  return Math.floor((this.numAnswered_ / this.numQuestions_) * 100);
};
